package cn.dsp.admin.service.impl;

import cn.dsp.admin.entity.UserRole;
import cn.dsp.admin.entity.admin.Admin;
import cn.dsp.admin.entity.admin.Role;
import cn.dsp.admin.entity.lot.Lot;
import cn.dsp.admin.mapper.AdminMapper;
import cn.dsp.admin.service.IAdminService;
import cn.dsp.admin.service.ILotService;
import cn.dsp.admin.service.IRoleService;
import cn.dsp.admin.service.ex.*;
import cn.dsp.admin.utils.IteratorUtils;
import cn.dsp.admin.vo.AdminVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class AdminServiceImpl implements IAdminService {


    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private ILotService lotService;

    @Override
    public void reg(Admin admin,String createdUser,Integer storeId) {
        // 从参数admin对象中获取用户名
        String adminName = admin.getAdminName();
        // 调用adminMapper根据用户名查询用户数据
        Admin result = findByAdminName(adminName);
        try {
            //检查用户名是否不存在！
            checkAdminNonExistent(result,adminName);
        } catch (Exception e) {
            throw e;
        }
        // 参数admin是客户端提交的注册数据，并不包含隐藏数据
        //  执行加密
        String password = admin.getPassword();
        String salt = UUID.randomUUID().toString();
        String md5Password = getMd5Password(password, salt);
        //  补全数据：salt
        admin.setSalt(salt);
        //  补全数据：加密后的密码
        admin.setPassword(md5Password);
        // 补全数据：is_delete、state、adminGrade，值为0
        admin.setIsDelete(0);
        admin.setState(0);
        admin.setStoreId(storeId);
        // 补全数据：4项日志，用户名为注册的用户名，时间为当前时间
        Date now = new Date();
        admin.setCreatedUser(createdUser);
        admin.setCreatedTime(now);
        admin.setModifiedUser(createdUser);
        admin.setModifiedTime(now);

        // 调用adminMapper的功能插入用户数据，实现注册.
        save(admin);
    }

    @Override
    public Admin login(String adminName, String password) {
        // 根据参数username查询用户数据
        Admin result = findByAdminName(adminName);
        //检查用户是否存在
        checkAdminExistence(result,adminName);
        // 从查询结果中取出盐值
        String salt = result.getSalt();
        // 调用getMd5Password()，基于参数password和盐值进行加密
        String md5Password = getMd5Password(password, salt);
        // 判断加密后的密码与查询结果中的密码是否不匹配
        if (!result.getPassword().equals(md5Password)) {
            // 是：密码错误，抛出PasswordNotMatchException
            throw new PasswordNotMatchException("密码错误,请重试！");
        }
        // 将查询结果中不应该返回的字段设置为null
        // 例如：isDelete、createdUser、createdTime、modifiedUser、modifiedTime、password、salt
        //设置用户数据
        result.setSalt(null);
        result.setIsDelete(null);
        result.setCreatedTime(null);
        result.setCreatedUser(null);
        result.setModifiedTime(null);
        result.setModifiedUser(null);
        // 返回查询结果
        return result;
    }

    @Override
    public void changePassword(Integer adminId, String adminName, String oldPassword, String newPassword) {
        // 根据参数uid查询用户数据
        Admin result = findByAdminId(adminId);
        // 取出查询结果中的盐值
        String salt = result.getSalt();
        // 将参数oldPassword进行加密，得到oldMd5Password
        String oldMd5Password = getMd5Password(oldPassword, salt);
        // 判断查询结果中的password与oldMd5Password是否不匹配
        if (!oldMd5Password.equals(result.getPassword())) {
            // 是：密码验证失败，抛出PasswordNotMatchException
            throw new PasswordNotMatchException("原密码不正确");
        }
        // 将参数newPassword进行加密，得到newMd5Password
        String newMd5Password = getMd5Password(newPassword, salt);
        // 执行更新密码
        updatePassword(adminId, newMd5Password, adminName, new Date());

    }

    @Override
    public void changeInfo(Integer adminId, String modifiedUser, Admin admin) {
        // 通过参数adminId查询用户数据
        findByAdminId(adminId);
        // 将参数adminID封装到参数admin的adminId中
        admin.setAdminId(adminId);
        // 将参数adminName封装到参数admin的modifiedUser中
        admin.setModifiedUser(modifiedUser);
        // 创建时间对象，封装到参数admin的modifiedTime中
        admin.setModifiedTime(new Date());
        // 执行修改，并获取返回值
        updateInfo(admin);
    }

    @Override
    public void changeInfoByAdmin(Admin admin, String modifiedUser) {
        //查询用户是否存在
        findByAdminId(admin.getAdminId());
        //查询用户名是否重复！
        String adminName = admin.getAdminName();
        Admin result = findByAdminName(adminName);
        if (!adminName.equals(result.getAdminName())){
            checkAdminNonExistent(result,adminName);
        }
        admin.setModifiedUser(modifiedUser);
        admin.setModifiedTime(new Date());
        //执行修改
        updateInfoByAdmin(admin);
    }

    @Override
    public void changeAvatar(Integer adminId, String username, String avatar) {
        // 通过参数uid查询用户数据
        Admin result  = findByAdminId(adminId);
        // 执行修改，并获取返回值
        result.setAvatar(avatar);
        updateInfo(result);
    }

    @Override
    public Admin getByAdminId(Integer adminId) {
        // 通过参数adminId查询用户数据
        Admin result = findByAdminId(adminId);
        // 创建新的Admin对象
        Admin admin = new Admin();
        // 将查询结果中的 adminId,adminName,adminGrade,gender,phone封装到新对象中
        admin.setAdminId(result.getAdminId());//id
        admin.setAdminName(result.getAdminName());//用户名
        admin.setGender(result.getGender());//性别
        admin.setPhone(result.getPhone()); //电话
        admin.setAvatar(result.getAvatar()); //头像
        // 返回新对象
        return result;
    }

    @Override
    public Admin getByAdminName(String adminName) {
        return findByAdminName(adminName);
    }

    @Override
    public AdminVO getAdminVO(Integer adminId) {
        Admin admin = null;
        try {
            admin = findByAdminId(adminId);
        } catch (ServiceException e) {
           throw e;
        }
        AdminVO adminVO = new AdminVO();
        //将admin封装AdminVO
        adminVO.setAdminId(adminId);
        adminVO.setAdminName(admin.getAdminName());
        adminVO.setGender(admin.getGender());
        adminVO.setPhone(admin.getPhone());
        adminVO.setAvatar(admin.getAvatar());
        adminVO.setState(admin.getState());
        //商家id
        adminVO.setStoreId(admin.getStoreId());
        //将role封装到VO
        adminVO.setRoles(admin.getRoles());
        //将lot封装到VO
        Integer lotId = admin.getLotId();
        if (lotId!=null){
            Lot lot = lotService.getByLid(lotId);
            adminVO.setLotId(lotId);
            adminVO.setLotName(lot.getName());
        }
        return adminVO;
    }

    @Override
    public List<Admin> getAllAdmin(Integer storeId) {
        List<Admin> result = findAllAdmin();
        //遍历查询结果，移除非当前uid的数据
        //返回
         return new IteratorUtils().adminsIterator(result,storeId);

    }

    @Override
    public List<Admin> getAdminByTerm(Integer storeId,String term) {
        if (term.equals("FIND_RILE_NAME_NULL")){
            return getAllAdmin(storeId);
        }
        List<Admin> result = findAdminByTerm(term);
        return new IteratorUtils().adminsIterator(result,storeId);
    }

    @Override
    public void deleteByAdminId(Integer adminId) {
        findByAdminId(adminId);
        remove(adminId);
    }

    @Override
    public void deleteAllRole(Integer adminId) {
        Integer rows = adminMapper.removeAllRole(adminId);
        if (rows<0){
            throw new DeleteException("删除数据失败！");
        }
    }

    @Override
    public UserRole getUserRole(UserRole userRole) {
        return adminMapper.findUserRole(userRole);
    }

    @Override
    public void adminAddRole(UserRole userRole) {
       UserRole result = getUserRole(userRole);
       if (result!=null){
           throw new UsernameConflictException("已存在该角色");
       }
       Integer rows = adminMapper.adminAddRole(userRole);
       if (rows!=1){
           throw new InsertException("添加角色失败");
       }
    }

    /**********************************************************************************************************************************/
    /**
     * 执行密码加密
     *
     * @param password 原密码
     * @param salt     盐值
     * @return 加密后的密码
     */
    private String getMd5Password(String password, String salt) {
        //加密规则：在原密码的左侧和右侧均拼接盐值，循环三次
        String str = salt + password + salt;
        for (int i = 0; i < 5; i++) {
            str = DigestUtils.md5DigestAsHex(str.getBytes());
        }
        return str;
    }

    /**
     * 插入管理员数据
     *
     * @param admin 管理员数据
     * @return 受影响的行数
     */
    private void save(Admin admin) {
        System.out.println(admin);
        Integer rows = adminMapper.save(admin);
        // 判断以上返回值是否不为1
        if (rows != 1) {
            // 是：插入用户数据失败，抛出InsertException
            throw new InsertException("插入用户数据时出现未知错误");
        }
    }

    /**
     * 更新密码
     *
     * @param adminId      管理员id
     * @param password     密码
     * @param modifiedUser 修改用户
     * @param modifiedTime 修改实际
     * @return
     */
    private void updatePassword(Integer adminId, String password, String modifiedUser, Date modifiedTime) {
        Integer rows = adminMapper.updatePassword(adminId, password, modifiedUser, modifiedTime);
        // 判断返回的受影响的行数是否不为1
        if (rows != 1) {
            // 是：更新失败，抛出UpdateException
            throw new UpdateException("修改密码时出现未知错误");
        }
    }

    /**
     * 修改管理员个人资料
     *
     * @param admin 修改的用户
     * @return 受影响的行数
     */
    private void updateInfo(Admin admin) {
         Integer rows = adminMapper.updateInfo(admin);
        // 判断返回的受影响的行数是否不为1
        if (!rows.equals(1)) {
            // 是：更新错误，抛出UpdateException
            throw new UpdateException("更新数据时发生未知错误！");
        }
    }

    /**
     * 管理员修改资料
     */
    private void updateInfoByAdmin(Admin admin){
        Integer rows = adminMapper.updateInfoByAdmin(admin);
        if (rows!=1){
            throw new UpdateException("修改失败!");
        }
    }

    /**
     * 根据管理员id查找用户数据
     *
     * @param adminId 管理员id
     * @return 匹配的管理员数据，如果没有匹配的数据，则返回null
     */
    private Admin findByAdminId(Integer adminId) {
        Admin result = adminMapper.findByAdminId(adminId);
        // 判断查询结果是否为null
        if (result == null) {
            // 是：用户名不存在，抛出UserNotFoundException
            throw new UserNotFoundException("用户名不存在");
        }
        // 判断查询结果中的isDelete是否为1
        if (result.getIsDelete().equals(1)) {
            // 是：用户被标记为已删除，抛出UserNotFoundException
            throw new UserNotFoundException("用户已被注销");
        }
        return result;
    }

    /**
     * 根据管理员用户名查找用户数据
     *
     * @param adminName 管理员用户名
     * @return 匹配的管理员数据，如果没有匹配的数据，则返回null
     */
    private Admin findByAdminName(String adminName) {
        return adminMapper.findByAdminName(adminName);
    }

    /**
     * 显示所有角色信息
     * @return
     */
    List<Admin> findAllAdmin(){
        return adminMapper.findAllAdmin();
    }

    /**
     *  根据角色名称查询符合的角色信息
     */
    List<Admin> findAdminByTerm(String term){
        return adminMapper.findAdminByTerm(term);
    }

    /**
     * 删除角色信息数据
     */
   private void remove(Integer adminId){
        Integer rows = adminMapper.remove(adminId);
        if (rows!=1){
            throw new DeleteException("删除数据失败！");
        }
    }

    /**
     * 判断用户是否存在
     */
    private void checkAdminExistence(Admin result,String adminName){
        // 判断查询结果是否为null
        if (result == null) {
            // 是：用户名不存在，抛出UserNotFoundException
            throw new UserNotFoundException("用户名(" + adminName + ")不存在");
        }
        // 判断查询结果中的isDelete是否为1
        if (result.getIsDelete().equals(1)) {
            // 是：用户被标记为已删除，抛出UserNotFoundException
            throw new UserNotFoundException("用户(" + adminName + ")已注销");
        }
    }
    private void checkAdminNonExistent(Admin result,String adminName){
        // 判断查询结果是否不为null
        if (result != null) {
            // 是：用户名已存在，不允许注册，抛出adminNameConflictException异常
            throw new UsernameConflictException("用户名(" + adminName + ")已经被占用");
        }
    }


}
